//
// Created by luo on 2022-10-17.
//

#ifndef ARMOR_DETECT_BUFF_DETECT_H
#define ARMOR_DETECT_BUFF_DETECT_H

#pragma once
#include<opencv2/opencv.hpp>
#include <cstdio>
#include <cmath>
//#include <opencv2/dnn.hpp>
using namespace cv;
using namespace std;


constexpr int Horizontal_Distance= 685;
constexpr int Radius= 70;
#define PI 3.1415926

// enum{
// 	FAKE=0,
// };


class Circle_center
{
public:
    Circle_center(){}
    ~Circle_center(){}
public:
    cv::Point2f vertices[4];          //Բ�ľ��δ洢�ĵ�
    cv::Point2f circle_center;        //Բ��2d��
    cv::Point3f circle_center_3d;	  //Բ��3d��
    cv::Rect circle_rect;
    float area_rate = 0;              //���������㼯�����ֵ
    float arclength_rate = 0;         //�����ܳ���㼯�ܳ���ֵ
    float circle_area=0;
    float distance_to_rect;
    bool is_center = false;			  //�Ƿ��ҵ�Բ��
};

class  Target_Buff
{
public:
    Target_Buff() {}
    ~Target_Buff() {}
public:
    cv::Point2f vertices[4];            //��Ҷ�洢�ĵ�
    cv::Point2f center;                 //��ҶԲ��
    cv::RotatedRect Rotation_rect;      //�ҵ�����ת����
    int contours_size = 200;            //��Ҷ�㼯��
    float angle = 0;                    //��Ҷ�ĽǶ�
    float area;                         //��Ҷ�����
    float area_rate = 0;                //���������㼯�����ֵ
    float arclength = 0;                //�����ܳ�
    float arclength_rate = 0;           //�����ܳ���㼯�ܳ���ֵ
    bool is_target_buff = false;		//�Ƿ��ҵ�Ŀ��װ�װ�
    std::vector<cv::Point2f> big_armor_points;
};

class Buff								//����Ҷ
{
public:
    Buff(){}
    ~Buff(){}
public:
    cv::Point2f vertices[4];            //��Ҷ�洢�ĵ�
    cv::Point2f center;                 //��ҶԲ��
    cv::RotatedRect Rotation_rect;       //�ҵ�����ת����

    float angle = 0;                    //��Ҷ�ĽǶ�
    float area;                         //��Ҷ�����
    float area_rate = 0;                //���������㼯�����ֵ
    float arclength = 0;                //�����ܳ�
    float arclength_rate = 0;           //�����ܳ���㼯�ܳ���ֵ
    float max_length_half=0;
    bool is_big_fan = false;			//�Ƿ��ҵ�Ŀ���װ�װ�
    int contours_size = 200;            //��Ҷ�㼯��
};

class buffdistinguish
{
public:

    buffdistinguish();
    ~buffdistinguish(){}
    void dection(Target_Buff &_Buff,const cv::Mat &frame, int Mode, vector<cv::Point2d> &m_Points, string Owecolor);                 //ִ�д���
    /*��ֵ������
    param frame
    */
    void imagePreprocess(cv::Mat &frame, std::string &Owecolor);  //ͼ��Ԥ����
    /*yoloʶ������װ�װ�
    param frame
    */
    bool yolo_dection(const Mat &src, Mat &debug_src);

    //----------��С���˷����Բ------------//
    bool LeastSquaresCircleFitting(vector<cv::Point2d> &m_Points);


    //----------��֤roi��ͼ��ȷ-------------//
    bool makeRectSafe(const Rect rect, const Size size);

    //----------�õ�ͼ��ROI-----------//
    void getROI(Buff &fan_param);

    //----------�ҵ�����������-----------//
    bool findRect(const cv::Mat & frame_clone, vector<cv::Point2d> &m_Points);


    //----------��ͳ����������ֱ����Բ��----------//
    cv::Point2f findCircleCenter(Circle_center &circle_param, float area,Buff fan_param);

    //----------�õ��������ת����------------//
    int get_direction(float angle);

    //----------�õ������λ������------------//
    bool rotation_direction(cv::RotatedRect &predict_Rect);

    //----------�õ�ǹ�ܴ���ľ�������------------//
    void get_gun_absoltion_point(float pit_angle, float yaw_angle);

    //----------Ԥ������λ��------------//
    void prediect_buff(cv::RotatedRect &predict_Rect,cv::Point2f predict_newpoint, float angle);

    //----------�����������õ�����ľ�������----------//
    void get_absoltion_point(double angle,bool x, bool y);


    //��������������Ŀ������--------------//
    void target_armor_height();

    //---------- kalmanԤ���¸������----------------//
    cv::Point2f calcPoint(Point2f center, double R, float predict_angle);

    void kalman_predict();



    cv::RotatedRect Circle_rect;               //������Բ�ĵľ���
    cv::RotatedRect box1;                      //��ˮ����ҵ�����ת����

    cv::RotatedRect new_rotaterect;
    cv::Rect roi_rect, m_roi_rect_last;
    cv::Rect m_img_rect;


    cv::Mat debug_src;
    cv::Mat dect_src;
    cv::Mat final_image;                        //�Ҷ�ͼ��ͼ��ͨ�������ͼ����Ľ��ͼ


    Point2f min_center, new_center;

    std::vector<cv::RotatedRect> vector_rect;  //�洢�ҵ�������
    std::vector<cv::RotatedRect> center_rect;  //�洢�ҵ���Բ����Ӿ���
    std::vector<int> conIndexs;                //�洢�ҵ���Բ����Ӿ�������Ա���ROI
    std::vector<float> vector_angle;
    std::vector<Circle_center> possible_center;		   //�洢���Կ��ܵ�Բ��
    //std::vector<float> possible_center_distance;

private:
    Target_Buff target_buff_param;

    //dnn::Net yolo_net;                         //yoloģ��
    cv::Mat frame_clone;                       //������Ƶ֡
    cv::Mat midImage;                          //ͨ���������ͼƬ
    cv::Mat ROI;

    cv::Point2f predict_newpoint;				//Ԥ��Բ��Բ��
    cv::Point2f Centroid;                       //圆心
    cv::Point2f m_Points2;                      //��֡ͼƬ�洢Բ������
    cv::Point2f circle_center;

    double dRadius;                             //����Բ�뾶
    double yaw_abs_angle;
    double pit_abs_angle;

    float angle;                                //��װ�װ�����ת�ĽǶ�
    float predict_angle;
    float pointDistance;
    float coordinate_x;
    float coordinate_y;
};

#endif //ARMOR_DETECT_BUFF_DETECT_H
